﻿using Subfaculty.Controllers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using RepositoriesInterfaces;
using System.Web.Mvc;
using Moq;
using Entities;
using System.Collections.Generic;
using Subfaculty.ViewModels;

namespace TestsSubfaculty
{
    [TestClass]
    public class AllocationControllerTest
    {
        private readonly Mock<IStudyPlanItemRepository> SPItemRep;
        private readonly Mock<IDisciplineRepository> DisciplineRep;
        private readonly Mock<IDepartmentRepository> DepartmentRep;
        private readonly Mock<IDirectionRepository> DirectionRep;
        private readonly Mock<IAllocationRepository> AllocationRep;
        private readonly Mock<IGroupRepository> GroupRep;
        private readonly Mock<ILoadAtomRepository> LoadAtomRep;
        private IList<Allocation> AllocationList;
        private IList<Direction> DirectionList;
        private IList<Department> DepartmentList;
        private IList<Discipline> DisciplineList;
        private IList<StudyPlanItem> SPItemsList;
        private IList<Group> GroupList;

        public AllocationControllerTest()
        {
            SPItemRep = new Mock<IStudyPlanItemRepository>();
            DisciplineRep = new Mock<IDisciplineRepository>();
            DepartmentRep = new Mock<IDepartmentRepository>();
            DirectionRep = new Mock<IDirectionRepository>();
            AllocationRep = new Mock<IAllocationRepository>();
            GroupRep = new Mock<IGroupRepository>();
            LoadAtomRep = new Mock<ILoadAtomRepository>();
            AllocationList = new List<Allocation>();
            DirectionList = new List<Direction>();
            DepartmentList = new List<Department>();
            DisciplineList = new List<Discipline>();
            SPItemsList = new List<StudyPlanItem>();
            GroupList = new List<Group>();
        }

        [TestMethod]
        public void GetAllocationListByChoosenDepartment_AllocationController()
        {
            // 1. Инициализация
            DepartmentRep.Setup(x => x.GetAll()).Returns(DepartmentList);
            AllocationRep.Setup(x => x.GetByDepartmentId(0)).Returns(AllocationList);

            // 2. Вызов метода
            var AllocationController = new AllocationController(SPItemRep.Object, AllocationRep.Object, DirectionRep.Object, DisciplineRep.Object, DepartmentRep.Object, GroupRep.Object, LoadAtomRep.Object);
            var result = AllocationController.Index(0) as ViewResult;

            // 3. Проверка результата
            var returnedModel = (AllocationListViewModel)result.Model;
            Assert.AreEqual((IEnumerable<Allocation>)AllocationList, returnedModel.Allocations);
        }

        [TestMethod]
        public void DeleteAllocation_AllocationController()
        {
            // 1. Инициализация
            Mock<IList<StudyPlanItem>> moqSPIList = new Mock<IList<StudyPlanItem>>();
            SPItemsList.Add(new StudyPlanItem() { Department = new Department() { Id = 0 } });
            var AllocationForDelete = new Allocation() { StudyPlanItems = SPItemsList };
            AllocationRep.Setup(x => x.GetByID(0)).Returns(AllocationForDelete);
            AllocationRep.Setup(x => x.Delete(AllocationForDelete));            

            // 2. Вызов метода
            var AllocationController = new AllocationController(SPItemRep.Object, AllocationRep.Object, DirectionRep.Object, DisciplineRep.Object, DepartmentRep.Object, GroupRep.Object, LoadAtomRep.Object);
            var result = (RedirectToRouteResult)AllocationController.Delete(0);

            // 3. Проверка результата
            AllocationRep.Verify(x => x.Delete(AllocationForDelete), Times.Exactly(1));
            Assert.AreEqual("Index/0", result.RouteValues["action"]);
        }

        [TestMethod]
        public void GetStudyPlanItemsByChosenDirection_AllocationController()
        {
            // 1. Инициализация
            SPItemRep.Setup(x => x.GetByDirectionId(0)).Returns(SPItemsList);            
            
            // 2. Вызов метода
            var AllocationController = new AllocationController(SPItemRep.Object, AllocationRep.Object, DirectionRep.Object, DisciplineRep.Object, DepartmentRep.Object, GroupRep.Object, LoadAtomRep.Object);
            var result = AllocationController.ajaxGetSPIListByDirection(0) as PartialViewResult;

            // 3. Проверка результата
            var returnedModel = (AjaxUpdateSPIListViewModel)result.Model;
            Assert.AreEqual(SPItemsList, returnedModel.StudyPlanItemList);
        }

        [TestMethod]
        public void GetSameSPItemsList_AllocationController()
        {
            // 1. Инициализация
            SPItemRep.Setup(x => x.GetSameSPIItem(0)).Returns(SPItemsList);

            // 2. Вызов метода
            var AllocationController = new AllocationController(SPItemRep.Object, AllocationRep.Object, DirectionRep.Object, DisciplineRep.Object, DepartmentRep.Object, GroupRep.Object, LoadAtomRep.Object);
            var result = AllocationController.ajaxGetSameSPIList(0) as PartialViewResult;

            // 3. Проверка результата
            var returnedModel = (AjaxUpdateSPIListViewModel)result.Model;
            Assert.AreEqual(SPItemsList, returnedModel.StudyPlanItemList);
        }

        [TestMethod]
        public void GetGroupListBySPItemsId_AllocationController()
        {
            // 1. Инициализация
            SPItemRep.Setup(x => x.GetByID(It.IsAny<int>())).Returns(new StudyPlanItem());
            GroupRep.Setup(x => x.GetBySPItemsList(It.IsAny<IList<StudyPlanItem>>())).Returns(GroupList);

            // 2. Вызов метода
            var AllocationController = new AllocationController(SPItemRep.Object, AllocationRep.Object, DirectionRep.Object, DisciplineRep.Object, DepartmentRep.Object, GroupRep.Object, LoadAtomRep.Object);
            var result = AllocationController.ajaxUpdateGroupList("0_1_2_3") as PartialViewResult;

            // 3. Проверка результата
            var returnedModel = (AjaxUpdateGroupListViewModel)result.Model;
            Assert.AreEqual(GroupList, returnedModel.GroupsList);
        }
    }
}
